{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Tutoria: Basic Tools wey you need for Private Deep Learning\n",
    "\n",
    "Make you na welicome to Pysyft's introductory tutoria wey dey preserve privacy and also dey make deep learning dey accessible for everybodi. This series of notebooks na the tori wey go make you know the new tools and techniques wey you need to get before you go fit dey do deep learning on secret/private data/models so that everybodi go fit get am.\n",
    "\n",
    "**Scope:** Make you know sey we no go onli talk about how to make everbodi get am/ protect the data from tiff, but we go talk about how Pysyft fit helep everybodi get control of their data, we go talk about Databases where we keep data and how we fit go ask for am, we got talk about neural models wey we fit use to commot information from data. We no sey nobodi dey one place, so as we dey add more tins to Pysyft, we go dey put am here and this tutorial go dey explain how we go dey use am. All of us go come dey happy.\n",
    "\n",
    "\n",
    "Person wey write am:\n",
    "- Andrew Trask - Twitter: [@iamtrask](https://twitter.com/iamtrask)\n",
    "\n",
    "Person wey translate am:\n",
    "- Temitọpẹ Ọladokun - Twitter: [@techie991](https://twitter.com/techie991)\n",
    "\n",
    "\n",
    "## Outline:\n",
    "\n",
    "- Part 1: Basic Tools wey you need for Private Deep Learning\n",
    "\n",
    "\n",
    "## You know why this tutoria dey important?\n",
    "\n",
    "**1) Competitive Career Advantage** - For 20 years wey digital revolution don dey start, tins don dey change oh. Tins like: data don dey berekete because computer don helep us dey reduce the things wey humanbeings dey do by dem sef and as computer dey helep us he come dey commot data. As data come dey berekete, [GDPR](https://eugdpr.org/) new regulation dey control how companies fit use the data - and more importantly how dey fit use personal information. You no sey my matter na my matter, make everybodi mind their business. **Bottom Line:** Scientist wey dey study data for school no get the right tools to access data because dey still dey use \"old school\" tools, but if you come learn Private Deep Learning tools, YOU go dey lead you mate and you go come get competitive advantage for your career.\n",
    "\n",
    "**2) Entreprenuerial Opportunities** - Wahala wey Deep Learning fit solve for our society dey too plenti, but this important problem neva get solution because we go need access to incredibly sensitive information about the people wey wan use the solution(imagine sey I wan use Deep Learning to helep person wey get mental and relationship palava!). He go hard make dem give you the data. You know sey na key dey open any door so if you learn Private Deep Learning, you don get the key to unlock startup opportunities wey person wey no get the key no go fit open.\n",
    "\n",
    "**3)Social Good** - In this life wey wahala dey so, Deep Learning fit solve them for us. Deep Learning on *personal information* na Deep Learning about people, *for people*. To dey learn how to do Deep Learning on top data wey no be your own na serious career and entrepreneurial opportunity, this one go give person opportunity to helep solve some of the most personal and important problems wey dey people life. You go fit solve this wahala on a large scale wey he touch plenti life.\n",
    "\n",
    "## If you do the tins wey dey below, we go get extra credit. \n",
    "\n",
    "- Make you Star PySyft when you reach GitHub! - [https://github.com/OpenMined/PySyft](https://github.com/OpenMined/PySyft)\n",
    "- Make you use Youtube video teach this notebook!\n",
    "\n",
    "Oya make we carry go !!!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Part -1: Prerequisites\n",
    "\n",
    "- Know PyTorch wella - if you no know am use this link to learn http://fast.ai course, if you don finish the course come back.\n",
    "- Read the PySyft Framework Paper https://arxiv.org/pdf/1811.04017.pdf! If you read am wella, you go don get the background knowledge on how we build Pysyft and you go come understand am wella."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Part 0: Setup\n",
    "\n",
    "Before you start anytin, check if everytin wey you need don dey installed. To do this, carry go Pysyft's readme and follow all the tins wey you suppose do. TLDR for plent people na.\n",
    "\n",
    "- Install Python 3.6 or higher\n",
    "- Install PyTorch 1.4\n",
    "- pip install syft[udacity]\n",
    "\n",
    "If you follow all the tins but he no come work(or any of the steps come fail) - first check the [README]\n",
    "(https://github.com/OpenMined/PySyft.git) for installation help and then make you open GitHub Issue or ping #beginner channel wey dey our slack! [slack.openmined.org](http://slack.openmined.org/). We go helep you because we full ground berekete."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Run this cell to see if things work\n",
    "import sys\n",
    "\n",
    "import torch\n",
    "from torch.nn import Parameter\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "import syft as sy\n",
    "hook = sy.TorchHook(torch)\n",
    "\n",
    "torch.tensor([1,2,3,4,5])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If this cells work, you don start the race be that! Oya make we carry go! "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Part 1: Basic Tools wey need for Private, Decentralized Data Science\n",
    "\n",
    "You know sey Deep Learning need data. I know sey you go come dey think sey how you go train a model when you get the data wey you go use?\n",
    "\n",
    "The answer simple die. If you dey use Pytorch, I know sey you go sabi how dem dey use torch.tensor objects like the cell wey dey below.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = torch.tensor([1,2,3,4,5])\n",
    "y = x + x\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To dey use these super fancy (and powerful!) tenseors dey important, but data must to dey your local machine. Na here we go start work.\n",
    "\n",
    "# Section 1.1 - Make we send Tensors go Bob's Machine\n",
    "\n",
    "Normally na to dey do data science/ deep learning on top machine wey get data, as we dey so we want perform this kind computation on some  **other** machine. He come dey clear to us now sey, we no fit assume sey the data dey our machine.\n",
    "\n",
    "As we no come sure, instead make we go use Torch tensors, now we go come work with **pointers** to tensors. Make I show you wetin I dey talk. First of all, we go create a \"pretend\" machine wey \"pretend\" person get - we go call am Bob."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "bob = sy.VirtualWorker(hook, id=\"bob\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Make we say Bob machine dey another planet - make we say Mars!  This time wey we dey talk, the machine dey empty. Oya make we create data wey we go send to Bob and make we come learn about pointers!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = torch.tensor([1,2,3,4,5])\n",
    "y = torch.tensor([1,1,1,1,1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Na now we go send tensors to Bob!!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_ptr = x.send(bob)\n",
    "y_ptr = y.send(bob)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_ptr"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "BOOM! Bob don get two tensors! You no believe me? Look am yourself!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "bob._objects"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "z = x_ptr + x_ptr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "z"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "bob._objects"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Look this tin wella. You know sey when we call `x.send(bob)` he return a new object wey we call `x_ptr`. This one na our first *pointer* to a tensor. Pointers to tensors no dey hold data by themselves. Instead, they just contain metadata about a tensor (with data) wey we store on top another machine. The purpose of these tensors na to give us intuitive API wey go tell other machine to compute functions wey dey use this tensor. Make we look metadata wey pointers contain."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_ptr"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Look that metadata wella!\n",
    "\n",
    "He get two main attributes wey pointers get:\n",
    "\n",
    "- `x_ptr.location : bob`, the location, reference to the location wey the pointer dey point\n",
    "- `x_ptr.id_at_location : <random integer>`, the id where the tensor dey stored at location\n",
    "\n",
    "Na this format dem dey print am `<id_at_location>@<location>`\n",
    "\n",
    "He still get other generic attributes:\n",
    "- `x_ptr.id : <random integer>`, the id of our pointer tensor, it was allocated randomly\n",
    "- `x_ptr.owner : \"me\"`, the worker wey be the owner of the pointer tensor, here na the local worker, make we say \"me\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_ptr.location"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "bob"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "bob == x_ptr.location"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_ptr.id_at_location"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_ptr.owner"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You fit dey reason why the local worker wey own the pointer na VirtualWorker, although we no create am.\n",
    "Make you laugh small, just as we get VirtualWorker object for Bob, we dey always have one for us. We fit create this worker automatically when we call `hook = sy.TorchHook()` so no disturb yourself about creating it yourself."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "me = sy.local_worker\n",
    "me"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "me == x_ptr.owner"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As we done dey end, just as we call .send() on a tensor, we fit call .get() on a pointer to a tensor to get am back!!!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_ptr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_ptr.get()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_ptr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_ptr.get()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "z.get()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "bob._objects"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As you don see sey Bob no get the tensors again!!! They don go back to our machine!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Section 1.2 - Make we use Tensor Pointers\n",
    "\n",
    "To dey send and receive tensors from Bob dey great, but the tin dey hard too dey do in Deep Learning! We wan make sure sey we fit perform tensor _operations_ on remote tensors. As luck come dey my side, tensors pointers dey make am dey easy. You fit use pointers as you dey use normal tensors!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = torch.tensor([1,2,3,4,5]).send(bob)\n",
    "y = torch.tensor([1,1,1,1,1]).send(bob)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "z = x + y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "z"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And voilà! \n",
    "\n",
    "Powerful sometin dey happen behind the scenes. Instead make we compute x and y on locally, we go run command wey dey serialized and go come send am to Bob, who go perform the computation, tensor z go dey created, and then returned the pointer to z wey go come back to us!\n",
    "\n",
    "If we call .get() on the pointer, we go receive the result back to our machine!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "z.get()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Torch Functions\n",
    "\n",
    "We don extend this API to all Torch operations!!!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "z = torch.add(x,y)\n",
    "z"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "z.get()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Variables (including backpropagation!)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = torch.tensor([1,2,3,4,5.], requires_grad=True).send(bob)\n",
    "y = torch.tensor([1,1,1,1,1.], requires_grad=True).send(bob)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "z = (x + y).sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "z.backward()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = x.get()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x.grad"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As we don see sey API dey flexible and capable of performing any operation we fit perform in Torch on *remote data*. This one go prepare our mind for advance privacy preserving protocols as in Federated Learning, Secure Multi-Party Computation, and Differential Privacy !"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Congratulations!!! - Oya Join the Community!\n",
    "\n",
    "Clap for una sef as you don finish this notebook tutorial! If you enjoy am and you wan join the movement towards privacy preserving, decentralized ownership of AI and the AI supply chain (data), follow the steps wey dey below.\n",
    "\n",
    "### Star PySyft on GitHub\n",
    "\n",
    "The easiset way to helep our community na to star the GitHub repos! This go helep raise awareness of the tools we dey build.\n",
    "\n",
    "- [Star PySyft](https://github.com/OpenMined/PySyft)\n",
    "\n",
    "### Join our Slack!\n",
    "\n",
    "To follow up bumper to bumper on how latest advancements, join our community! You can do so by filling out the form at [http://slack.openmined.org](http://slack.openmined.org)\n",
    "\n",
    "### Join a Code Project!\n",
    "\n",
    "The best way to contribute to our community na to become code contributor! You fit go to PySyft GitHub Issues page and filter for \"Projects\". E go show you all the top level Tickets giving an overview of what projects you fit join! If you no wan join any project, but you wan code small, you fit look for more \"one off\" mini-projects by searching for GitHub issues marked \"good first issue\"\n",
    "\n",
    "- [PySyft Projects](https://github.com/OpenMined/PySyft/issues?q=is%3Aopen+is%3Aissue+label%3AProject)\n",
    "- [Good First Issue Tickets](https://github.com/OpenMined/PySyft/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)\n",
    "\n",
    "### Donate\n",
    "\n",
    "If you no get time to contribute to our codebase, but still like to lend support, you fit be a Backer on our Open Collective. All donations wey we get na for our web hosting and other community expenses such as hackathons and meetups! meetups!\n",
    "\n",
    "[OpenMined's Open Collective Page](https://opencollective.com/openmined)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
